-- Copyright (c) 2024 Huawei Technologies Co., Ltd.
-- openUBMC is licensed under Mulan PSL v2.
-- You can use this software according to the terms and conditions of the Mulan PSL v2.
-- You may obtain a copy of Mulan PSL v2 at:
--         http://license.coscl.org.cn/MulanPSL2
-- THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
-- EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
-- MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
-- See the Mulan PSL v2 for more details.

local class = require 'mc.class'
local log = require 'mc.logging'
local ini_parse = require 'mc.v2_persistence'

-- 保证此数是UPGRADE_GROUP_MEM_CNT的整数倍，否则数组操作会越界--BTD
local UPGRADE_MAX_COMPNENT_NUM = 32

local PackageCfg = class()

local FirmwareCfg = class()

local function string_split(str)
    local array = {}
    for value in string.gmatch(str, '[^,]+') do
        array[#array + 1] = value
    end
    return array
end

function FirmwareCfg:ctor(firmware_name, firmware_info)
    self.name = firmware_name
    self.product_id = tonumber(firmware_info.ProductID)
    -- 标识固件对应的组件类型，天池场景EXU为主板（0X05），其他组件均认为是背板(0X24)
    self.component_id = tonumber(firmware_info.ComponentID)
    -- 标识天池组件类型，非标字段可能为空
    self.idex = tonumber(firmware_info.ComponentIDEx)
    self.board_id = tonumber(firmware_info.BoardID)
    if firmware_info.Uid then
        self.uid_list = string_split(firmware_info.Uid)
    end
end

local function get_subcomponents(subcomponent_list, firmware, data)
    local component_num = tonumber(firmware.SubComponentNum)
    if not component_num then
        return
    end
    for i = 1, component_num do
        local component_name = string.format("SubComponent%d", i)
        if data[component_name] and data[component_name].Firmwareid then
            subcomponent_list[tonumber(data[component_name].Firmwareid)] = data[component_name]
            log:notice("[bios]get package subcomponent(%s) id (%s)", component_name, data[component_name].Firmwareid)
        end
    end
end

local function parse(path)
    if not path then
        log:error("[bios]parse update cfg: get cfg path nil")
        error('parse cfg fail')
    end
    local data = ini_parse.load_file(path)
    if (not data.Basic) or (not data.Basic.Version) then
        log:error('[bios]parse update cfg: get Basic Version failed')
        error('parse cfg fail')
    end
    local update_file_num = tonumber(data.Firmware.FileNum)
    if update_file_num == 0 or update_file_num > UPGRADE_MAX_COMPNENT_NUM then
        log:error('[bios]parse update cfg: Update file num is invalid')
        error('parse cfg fail')
    end
    local firmware_list = {}
    local subcomponent_list = {}
    local group_name
    local package_type
    for i = 2, update_file_num do -- 第1个Firmware指的就是配置文件，所以从2开始
        group_name = string.format("Firmware%d", (i - 1))
        log:notice("[bios]get package cfg %s", group_name)
        table.insert(firmware_list, FirmwareCfg.new(group_name, data[group_name]))
        get_subcomponents(subcomponent_list, data[group_name], data)
        package_type = data[group_name].PackageType
    end
    return data, firmware_list, subcomponent_list, package_type
end

function PackageCfg:ctor(path)
    local cfg_data, firmware_list, subcomponent_list, package_type = parse(path)
    local cfg = {}
    cfg.basic = cfg_data.Basic
    cfg.firmware_overview = cfg_data.Firmware
    cfg.firmware_list = firmware_list
    cfg.subcomponent_list = subcomponent_list
    cfg.package_type = package_type
    self.cfg = cfg
end

function PackageCfg:get_cfg()
    return self.cfg
end

return PackageCfg